#include "httplib.h"
#include <filesystem>
#include <opencv2/opencv.hpp>
#include <nlohmann/json.hpp>
#include <chrono>
#include <iomanip>
#include <sstream>

const std::string IMAGE_BASE_DIR = "/opt/app_images";
const std::string HTTP_BASE_URL = "http://127.0.0.1:8085/images";

std::string getTimestampString()
{
    auto now = std::chrono::system_clock::now();
    auto now_c = std::chrono::system_clock::to_time_t(now);
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                      now.time_since_epoch()) %
                  1000;

    std::stringstream ss;
    ss << std::put_time(std::localtime(&now_c), "%Y%m%d%H%M%S")
       << std::setfill('0') << std::setw(3) << now_ms.count();
    return ss.str();
}

// 获取服务器IP地址的函数
std::string get_server_ip()
{
    struct ifaddrs *ifaddr, *ifa;
    char host[NI_MAXHOST];
    std::string ip = "127.0.0.1"; // 默认值

    if (getifaddrs(&ifaddr) == -1)
    {
        perror("getifaddrs");
        return ip;
    }

    // 遍历所有网络接口
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
    {
        if (ifa->ifa_addr == NULL)
            continue;

        int family = ifa->ifa_addr->sa_family;

        // 只处理IPv4接口
        if (family == AF_INET)
        { // IPv4
            int s = getnameinfo(ifa->ifa_addr,
                                sizeof(struct sockaddr_in),
                                host, NI_MAXHOST,
                                NULL, 0, NI_NUMERICHOST);
            if (s != 0)
            {
                continue;
            }

            // 排除回环接口
            if (strcmp(ifa->ifa_name, "lo") != 0)
            {
                ip = host;
                // 优先选择非回环的IPv4地址
                if (ip != "127.0.0.1")
                {
                    break;
                }
            }
        }
    }
    freeifaddrs(ifaddr);
    return ip;
}

void run_image_server()
{
    httplib::Server server;
    std::string server_ip = get_server_ip();

    // 图片上传接口
    server.Post("/upload", [&server_ip](const httplib::Request &req, httplib::Response &res)
                {
                    std::cout << "Received upload request" << std::endl;
        try {
            nlohmann::json j = nlohmann::json::parse(req.body);
            std::string table = j["table"];
            std::string hex_data = j["image"];
            std::string suffix = j.value("suffix", "jpg");
            
            // 将十六进制字符串转换为二进制
            std::vector<uchar> binary_data;
            for (size_t i = 0; i < hex_data.length(); i += 2) {
                std::string byte_str = hex_data.substr(i, 2);
                uchar byte = static_cast<uchar>(std::stoi(byte_str, nullptr, 16));
                binary_data.push_back(byte);
            }
            
            // 获取完整时间戳并分割
            std::string timestamp = getTimestampString();
            std::string date_part = timestamp.substr(0, 8);   // 年月日 (YYYYMMDD)
            std::string time_part = timestamp.substr(8, 9);   // 时分秒毫秒 (HHMMSSmmm)
            
            std::string dir_name = table;
            // 创建日期目录和表目录
            std::string date_dir = IMAGE_BASE_DIR + "/" + date_part;
            std::string table_dir = date_dir + "/" + dir_name;
            std::filesystem::create_directories(table_dir);
            
            // 生成文件名：表名 + 时分秒毫秒
            std::string filename = dir_name + "_" + time_part + "." + suffix;
            std::string rel_path = date_part + "/" + dir_name + "/" + filename;
            std::string full_path = IMAGE_BASE_DIR + "/" + rel_path;
            
            // 保存图片
            cv::Mat image = cv::imdecode(binary_data, cv::IMREAD_COLOR);
            if (image.empty()) {
                res.status = 400;
                res.set_content("{\"error\": \"Failed to decode image\"}", "application/json");
                return;
            }
            
            if (!cv::imwrite(full_path, image)) {
                res.status = 500;
                res.set_content("{\"error\": \"Failed to save image\"}", "application/json");
                return;
            }
            
            // 返回图片URL "http://" + server_ip +
            std::string image_url =  "/images/" + rel_path;
            nlohmann::json response;
            response["url"] = image_url;
            res.set_content(response.dump(), "application/json");
        } catch (const std::exception& e) {
            res.status = 400;
            res.set_content("{\"error\": \"Invalid request format: " + std::string(e.what()) + "\"}", "application/json");
        } });

    // // 图片访问接口
    // server.set_base_dir(IMAGE_BASE_DIR.c_str());
    // server.Get("/images/(.*)", [](const httplib::Request &req, httplib::Response &res)
    //            {
    //     res.set_header("Cache-Control", "public, max-age=31536000");
    //     res.set_header("Content-Type", "image/jpeg"); });

    std::cout << "Image server running on port 8080\n";
    server.listen("0.0.0.0", 8080);
}